package main

import (
	"context"
	"fmt"
	"github.com/coreos/etcd/clientv3"
	"github.com/coreos/etcd/clientv3/naming"
	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
	"go-programming-tour-book/tag-service/internal/middleware"
	pb "go-programming-tour-book/tag-service/proto"
	"google.golang.org/grpc"
	"log"
	"time"
)

type Auth struct {
	AppKey    string
	AppSecret string
}

func (a *Auth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
	return map[string]string{"app_key": a.AppKey, "app_secret": a.AppSecret}, nil
}

func (a *Auth) RequireTransportSecurity() bool {
	return false
}

func main() {
	//auth := Auth{
	//	AppKey:    "go-programming-tour-book",
	//	AppSecret: "xyy",
	//}
	ctx := context.Background()
	//opts := []grpc.DialOption{grpc.WithPerRPCCredentials(&auth)}
	opts := []grpc.DialOption{grpc.WithUnaryInterceptor(
		grpc_middleware.ChainUnaryClient(
			middleware.UnaryContextTimeout(),
			middleware.ClientTracing(),
		))}
	clientConn, err := GetClientConn(ctx, "localhost:8004", opts) //[]grpc.DialOption{grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(middleware.UnaryContextTimeout()))})
	if err != nil {
		log.Fatalf("err: %v", err)
	}
	defer clientConn.Close()

	// 初始化指定 RPC Proto Service 的客户端实例对象
	tagServiceClient := pb.NewTagServiceClient(clientConn)
	resp, _ := tagServiceClient.GetTagList(
		ctx,
		&pb.GetTagListRequest{Name: "Go"},
	)
	log.Printf("resp: %v", resp)
}

func GetClientConn(ctx context.Context, serviceName string, opts []grpc.DialOption) (*grpc.ClientConn, error) {
	config := clientv3.Config{
		Endpoints:   []string{"http://192.168.239.128:2379"},
		DialTimeout: time.Second * 60,
	}
	cli, err := clientv3.New(config)
	if err != nil {
		return nil, err
	}

	r := &naming.GRPCResolver{Client: cli}
	target := fmt.Sprintf("/etcdv3://go-programming-tour/grpc/%s", serviceName)
	opts = append(opts, grpc.WithInsecure(),
		grpc.WithBalancer(grpc.RoundRobin(r)), grpc.WithBlock())

	return grpc.DialContext(ctx, target, opts...)

	//opts = append(opts, grpc.WithInsecure())
	////创建给定目标的客户端连接，注意，所要请求的服务端是非加密模式的，因此需要调用 grpc.WithInsecure 方法来禁用词 ClientConn 的传输安全性验证
	//return grpc.DialContext(ctx, target, opts...)
}
